home *** CD-ROM | disk | FTP | other *** search
- (c) Copyright 1990 Commodore-Amiga, Inc. All rights reserved.
- The information contained herein is subject to change without notice,
- and is provided "as is" without warranty of any kind, either express
- or implied. The entire risk as to the use of this information is
- assumed by the user.
-
- Identifying the Amiga's CPU
-
- by Dave Haynie
-
- Amiga's come in a variety of configurations including models that
- use the Motorola 68000, the 68020 and now the 68030. While it's
- not that difficult to figure out which CPU you're using by
- trying certain instructions and trapping the exception if they
- break, this isn't necessary. In fact, the Amiga OS sets an
- ExecBase flag on system startup that can identify which
- processor (and coprocessor) is installed. The CPU type flags are
- stored in ExecBase->AttnFlags.
-
- Under V1.3 and earlier versions of the OS, the system can't tell
- the difference between a 68020 and a 68030, or a 68881 and a
- 68882. That's no big surprise, since both the 68030 and 68882
- were introduced well after the last version of the OS was
- released. Under the new V2.0 version of the operating system,
- support for identifying these processors has been added. If you
- are running under V2.0 of the operating system, you can just look
- at ExecBase->AttnFlags to find out what processor is installed.
- The AttnFlags field will be set as follows:
-
- /****** V2.0 Bit defines for AttnFlags ************************/
-
- /* Processors and Co-processors: */
- #define AFB_68010 0 /* also set for 68020 */
- #define AFB_68020 1 /* also set for 68030 */
- #define AFB_68030 2 /* New flag under V2.0 */
- #define AFB_68040 3 /* New flag under V2.0 */
- #define AFB_68881 4 /* also set for 68882 */
- #define AFB_68882 5 /* New flag under V2.0 */
-
- #define AFF_68010 (1L<<0)
- #define AFF_68020 (1L<<1)
- #define AFF_68030 (1L<<2) /* New flag under V2.0 */
- #define AFF_68040 (1L<<3) /* New flag under V2.0 */
- #define AFF_68881 (1L<<4)
- #define AFF_68882 (1L<<5) /* New flag under V2.0 */
-
- However, if you are running under V1.3 or earlier versions of the
- operating system, this method will not work with the 68030 and
- 68882 processors. To overcome this problem you can use the code
- shown below to identify which CPU the system is using under
- V1.3. There are three functions to link with your code to
- identify the processor and coprocessor: GetCPUType(),
- GetFPUType(), and GetMMUType().
-
- o ULONG GetCPUType(void)
-
- Returns a number, representing the type of CPU in the
- system: 68000L, 68010L, 68020L, or 68030L.
-
- o ULONG GetFPUType(void)
-
- Returns a number, representing the type of FPU in the
- system: 0L (no FPU), 68881L, or 68882L.
-
- o ULONG GetMMUType(void)
-
- Returns a number, representing the type of MMU in the
- system: 0L (no MMU), 68851L, 68030L, or 0xFFFFFFFFL
- (this means an FPU responding to a MMU address).
-
-
- In order to find out which processor is present, GetCPUType()
- first checks ExecBase->AttnFlags. Under V1.3 if this is set to
- AFF_68020, then the processor may be either a 68020 or a 68030.
- GetCPUType() then checks to see if the processor is really a
- 68030 by trying to invert the instruction burst enable bit,
- which doesn't exist on the 68020. If that bit can be changed,
- then it is a 68030 system.
-
- Similar methods are used in GetMMUType() and GetFPUType(). These
- functions first look at ExecBase->AttnFlags and then do extra
- tests based on unique features of a given coprocessor to find out
- what is present in the system. The functions are listed below.
-
-
- ;
- ; From SetCPU V1.5
- ; by Dave Haynie
- ;
- ; 68030 Assembly Function Module
- ;
- ; This module contains functions that access features of the 68020,
- ; 68030, and 68851 chips, and ID all of these, plus the 68881/68882
- ; FPU chips, reset stuff, and exception handler.
- ;
-
-
-
- ;
- ; Macros & constants used herein...
- ;
-
-
- section code
-
- CALLSYS macro *
- jsr LVO\1(A6)
- endm
-
- CIB_ENABLE EQU 0
- CIB_FREEZE EQU 1
- CIB_ENTRY EQU 2
- CIB_CLEAR EQU 3
- CIB_BURST EQU 4
-
- CDB_ENABLE EQU 8
- CDB_FREEZE EQU 9
- CDB_ENTRY EQU 10
- CDB_CLEAR EQU 11
- CDB_BURST EQU 12
- CDB_WALLOC EQU 13
-
- AFB_68030 EQU 2
-
- ATNFLGS EQU $129
-
- LVOSupervisor EQU -30
- LVOSuperState EQU -150
- LVOFindTask EQU -294
- LVOAllocTrap EQU -342
- LVOFreeTrap EQU -348
-
-
- ;
- ; Need just a little more stuff
- ;
-
-
- NOLIST
- include "exec/execbase.i"
- include "exec/tasks.i"
- LIST
-
- * machine mc68020
- * mc68881
-
-
- ;**********************************************************************
- ;
- ; This section contains functions that identify and operate on CPU
- ; things.
- ;
- ;**********************************************************************
-
- XDEF _GetCPUType ; ID the CPU
- XDEF _GetFPUType ; ID the FPU
- XDEF _GetMMUType ; ID the MMU
-
-
- ;
- ; This function returns the type of the CPU in the system as a
- ; longword: 68000, 68010, 68020, or 68030. The testing must be done
- ; in reverse order, in that any higher CPU also has the bits set for
- ; a lower CPU. Also, since 1.3 doesn't recognize the 68030, if I
- ; find the 68020 bit set, I always check for the presence of a
- ; 68030.
- ;
- ; This routine should be the first test routine called under 1.2
- ; and 1.3.
- ;
- ; ULONG GetCPUType(void);
- ;
-
-
- _GetCPUType:
- movem.l a4/a5,-(sp) ; Save this register
- move.l 4,a6 ; Get ExecBase
- btst.b #AFB_68030,ATNFLGS(a6) ; Does the OS think an '030 is here?
- beq 0$
- move.l #68030,d0 ; Sure does...
- movem.l (sp)+,a4/a5
- rts
- 0$
- btst.b #AFB_68020,ATNFLGS(a6) ; Maybe a 68020?
- bne 2$
- btst.b #AFB_68010,ATNFLGS(a6) ; Maybe a 68010?
- bne 1$
- move.l #68000,d0 ; Just a humble '000
- movem.l (sp)+,a4/a5
- rts
- 1$
- move.l #68010,d0 ; Yup, we're an '010
- movem.l (sp)+,a4/a5
- rts
- 2$
- move.l #68020,d0 ; Assume we're an '020
- lea 3$,a5 ; Get the start of the supervisor code
- CALLSYS Supervisor
- movem.l (sp)+,a4/a5
- rts
- 3$
- movec cacr,d1 ; Get the cache register
- move.l d1,a4 ; Save it for a minute
- bset.l #CIB_BURST,d1 ; Set the inst burst bit
- bclr.l #CIB_ENABLE,d1 ; Clear the inst cache bit
- movec d1,cacr ; Try to set the CACR
- movec cacr,d1
- btst.l #CIB_BURST,d1 ; Do we have a set burst bit?
- beq 4$
- move.l #68030,d0 ; It's a 68030
- bset.b #AFB_68030,ATNFLGS(a6)
- 4$
- move.l a4,d1 ; Restore the original CACR
- movec d1,cacr
- rte
-
-
- ;
- ; This function returns 0L if the system contains no MMU,
- ; 68851L if the system does contain an 68851, or 68030L if the
- ; system contains a 68030 (built-in MMU).
- ;
- ; This code runs just fine on boards from Ronin and
- ; Commodore, as well as all 68030 boards it's been tested on.
- ;
- ; ULONG GetMMUType(void)
- ;
-
-
- _GetMMUType:
- move.l 4,a6 ; Get ExecBase
- movem.l a3/a4/a5,-(sp) ; Save this stuff
- move.l #0,a1
- CALLSYS FindTask ; Call FindTask(0L)
- move.l d0,a3
-
- move.l TC_TRAPCODE(a3),a4 ; Change the exception vector
- move.l #2$,TC_TRAPCODE(a3)
-
- move.l #-1,d0 ; Try to detect undecode FPU
- subq.l #4,sp ; Let's try an MMU instruction
- dc.w $f017 ; like PMOVE tc,(sp)
- dc.w $4200
- cmpi #0,d0 ; Any MMU here?
- beq 1$
- cmpi #-1,d0 ; Hardware "features"?
- beq 1$
- btst.b #AFB_68030,ATNFLGS(a6) ; Does the OS think an '030 is here?
- beq 1$
- move.l #68030,d0
-
- 1$
- addq.l #4,sp ; Return that local
- move.l a4,TC_TRAPCODE(a3) ; Reset exception stuff
- movem.l (sp)+,a3/a4/a5 ; and return the registers
- rts
-
- ; This is the exception code. No matter what machine we're on,
- ; we get an exception. If the MMU's in place, we should get a
- ; privilige violation; if not, an F-Line emulation exception.
- 2$
- move.l (sp)+,d0 ; Get Amiga supplied exception #
- cmpi #11,d0 ; Is it an F-Line?
- beq 3$ ; If so, go to the fail routine
- move.l #68851,d0 ; We have MMU
- addq.l #4,2(sp) ; Skip the MMU instruction
- rte
- 3$
- moveq.l #0,d0 ; It dinna woik,
- addq.l #4,2(sp) ; Skip the MMU instruction
- rte
-
- ;
- ; This function returns the type of the FPU in the system as a
- ; longword: 0 (no FPU), 68881, or 68882.
- ;
- ; ULONG GetFPUType(void);
- ;
-
-
- _GetFPUType:
- move.l a5,-(sp) ; Save this register
- move.l 4,a6 ; Get ExecBase
- btst.b #AFB_68881,ATNFLGS(a6) ; Does the OS think an FPU is here?
- bne 1$
- moveq.l #0,d0 ; No FPU here
- move.l (sp)+,a5 ; Give back the register
- rts
- 1$
- lea 2$,a5 ; Get the start of the supervisor code
- CALLSYS Supervisor
- move.l (sp)+,a5 ; Give back registers
- rts
- 2$
- move.l #68881,d0 ; Assume we're a 68881
- fsave -(sp) ; Test and check
- moveq.l #0,d1
- move.b 1(sp),d1 ; Size of this frame
- cmpi #$18,d1
- beq 3$
- move.l #68882,d0 ; It's a 68882
- 3$
- frestore (sp)+ ; Restore the stack
- rte
-
- end
-
-
-
-
-
-
-